package net.sansi.v3correctserver.service.project;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.extra.spring.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import net.sansi.v3correctserver.entity.space.ProjectSpaceCnf;
import net.sansi.v3correctserver.exception.ServiceException;
import net.sansi.v3correctserver.service.space.ProjectSpace;
import net.sansi.v3correctserver.service.space.SpaceService;
import net.sansi.v3correctserver.util.JacksonUtil;
import net.sansi.v3correctserver.util.LocalCache;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.util.List;

/**
 * Created by Fang
 * create time : 2024/11/1
 * IDE : IntelliJ IDEA
 */
@Service
@Slf4j
public class ProjectService {

    @Resource
    private SpaceService spaceService;

    // 项目配置文件名称
    private static final String PROJECT_CNF_FILE_NAME = "projects.json";

    public static ProjectService getInstance() {
        return SpringUtil.getBean(ProjectService.class);
    }

    // 项目配置缓存
    private static final LocalCache<List<ProjectSpaceCnf>> projectCnfCache = new LocalCache<>();

    /**
     * 获取项目空间配置列表
     *
     * @return 项目空间配置列表
     */
    public List<ProjectSpaceCnf> listProjectSpaceCnf() {
        return projectCnfCache.get(
                this.getClass(),
                () -> {
                    Path cnfPath = getProjectSpaceCnfPath();
                    if (!cnfPath.toFile().exists()) {
                        FileUtil.writeUtf8String("[]", cnfPath.toFile());
                    }
                    return JacksonUtil.readList(cnfPath.toFile(), ProjectSpaceCnf.class);
                }
        );
    }

    /**
     * 根据项目id获取项目空间配置
     *
     * @param projectId 项目id
     * @return 某个项目空间配置
     */
    public ProjectSpaceCnf getProjectSpaceCnfById(String projectId) {
        ProjectSpaceCnf one = CollUtil.findOne(
                listProjectSpaceCnf(),
                (cnf) -> cnf.getId().equals(projectId)
        );
        return one;
    }

    /**
     * 获取项目空间
     * 通过 ID 匹配
     *
     * @param projectId 项目id
     * @return 项目空间
     */
    public ProjectSpace getProjectSpaceById(String projectId) {
        return new ProjectSpace(getProjectSpaceCnfById(projectId));
    }

    /**
     * 添加项目空间配置
     *
     * @param cnf 配置文件
     * @return 添加后的配置文件
     */
    public ProjectSpaceCnf saveProjectSpaceCnf(ProjectSpaceCnf cnf) {
        Path spacePath = cnf.getSpacePath().normalize();
        if (!spacePath.toFile().exists()) {
            FileUtil.mkdir(spacePath);
        }
        List<ProjectSpaceCnf> cnfList = listProjectSpaceCnf();
        cnf.setId(IdUtil.randomUUID());
        cnf.setCreateTime(LocalDateTime.now());
        cnfList.add(cnf);
        saveProjectSpaceCnfList(cnfList);
        return cnf;
    }

    /**
     * 更新项目空间配置
     * 通过 ID 匹配
     *
     * @param cnf 项目空间配置
     * @return 更新后的项目空间配置
     */
    public ProjectSpaceCnf updateProjectSpaceCnf(ProjectSpaceCnf cnf) {
        List<ProjectSpaceCnf> cnfList = listProjectSpaceCnf();
        ProjectSpaceCnf one = CollUtil.findOne(cnfList, (c) -> c.getId().equals(cnf.getId()));
        if (one == null) throw new ServiceException("该项目不存在 [id] {} [name] {}", cnf.getId(), cnf.getName());
        one.setUpdateTime(LocalDateTime.now());
        BeanUtil.copyProperties(cnf, one);
        saveProjectSpaceCnfList(cnfList);
        return cnf;
    }

    /**
     * 保存或更新项目空间配置
     *
     * @param cnf 项目空间配置
     * @return 保存或更新后的项目空间配置
     */
    public ProjectSpaceCnf saveOrUpdateProjectSpaceCnf(ProjectSpaceCnf cnf) {
        if (getProjectSpaceCnfById(cnf.getId()) == null) {
            return saveProjectSpaceCnf(cnf);
        } else {
            return updateProjectSpaceCnf(cnf);
        }
    }

    /**
     * 保存项目空间配置列表
     *
     * @param list 项目空间配置列表
     */
    public void saveProjectSpaceCnfList(List<ProjectSpaceCnf> list) {
        FileUtil.writeUtf8String(
                JacksonUtil.toPrettyString(list),
                getProjectSpaceCnfPath().toFile()
        );
        projectCnfCache.put(this.getClass(), list);
    }

    /**
     * 获取项目配置文件路径
     *
     * @return 项目配置文件路径
     */
    public Path getProjectSpaceCnfPath() {
        return spaceService.getRootSpaceUtil().resolveFilename(PROJECT_CNF_FILE_NAME);
    }

    /**
     * 删除项目空间配置
     *
     * @param ids 项目id列表
     */
    public void removeByIds(List<String> ids) {
        List<ProjectSpaceCnf> configs = listProjectSpaceCnf();
        configs.removeIf(cnf -> ids.contains(cnf.getId()));
        saveProjectSpaceCnfList(configs);
    }

    public String exportProjectByIds(List<String> ids, String expoetPath) {
        // 检查所有项目 ID 是否存在
        //        List<ProjectSpaceCnf> projectSpaceCnfs = listProjectSpaceCnf();
        //        List<String> existingIds = projectSpaceCnfs.stream()
        //                .map(ProjectSpaceCnf::getId)
        //                .collect(Collectors.toList());
        //
        //        List<String> missingIds = ids.stream()
        //                .filter(id -> !existingIds.contains(id))
        //                .collect(Collectors.toList());
        //
        //        if (!missingIds.isEmpty()) {
        //            return "error";
        //        }
        //
        //        // 创建导出目录
        //        File exportDir = new File(expoetPath);
        //        if (!exportDir.exists()) {
        //            exportDir.mkdirs();
        //        }
        //
        //        // 创建临时文件夹来存储导出内容
        //        File tempZipFile = FileUtil.createTempFile("project-export-", ".zip", exportDir, true);
        //        // 遍历项目ID列表并压缩项目目录到临时文件
        //
        //        for (String id : ids) {
        //            ProjectSpaceCnf projectSpaceCnf = getProjectSpaceCnfById(id);
        //            Path projectPath = projectSpaceCnf.getSpacePath();
        //            File projectDir = projectPath.toFile();
        //
        //            if (projectDir.exists() && projectDir.isDirectory()) {
        //                // ZipUtil.zip(projectDir);
        //                ZipUtil.zip(projectDir, tempZipFile);
        //            }
        //            else {
        //                return "error2";
        //            }
        //        }

        return "";
    }
}
